#!/usr/bin/env python3
# encoding=utf-8


import datetime
import random
import unittest

from bson import ObjectId
from flask_jwt_extended import create_access_token

from app import create_app
from app.db.models.asset_tasks import AssetTasks
from app.db.models.inspection import IgnoreStrategies
from app.db.models.jobs import VulSettings
from app.db.models.tasks import Task
from app.db.models.users import User
from app.db.models.wass import ScanEvents
from app.libs.enums import (
    InspectionStrategyIgnoreType, InspectionStrategySwitchStatus, TaskType
)
from app.validators.cloud import DefenseSourceCheckForm


TEST_DATA_USERNAME = 'scanv_test@knownsec.com'
EVENT_ID_LIST = [
    '181c1361b1824b09b42f2ff1734b4743',
    '4aacf256f72f41eaa07c78fde50857d2',
    '2cbeb9334dcb4a869b78ec0de732520c',
    'c119d047a91a42edb76d8621e4cde0c6',
    'bde27b30168046bb9e716fc0bc3ab8c3',
    'a3d102a86d514f9ea72a5d2848676256',
    'eb1aeaea59734a78a5be3bd1d56ccbc7',
    'ca3f8a51f69348268e44d94245806db8',
    'ca1bb9a31b7f40269218527fcfbec8d2',
]
TASK_ID = '2446cdf429f84ed98b5b4c4b780b8851'
TASK_SESSION_ID = '2446cdf429f84ed98b5b4c4b780b8852'
JOB_ID = '2446cdf429f84ed98b5b4c4b780b8853'
TARGET_URL = 'http://example.com/'
URL = 'http://example.com/spider/similarurl/type4/6_index.php'
IGNORE_URL = 'http://example.com/ignore.html'
KEY = 'xss'


class BaseAPITestCase(unittest.TestCase):

    app = create_app()
    app_context = app.app_context()
    app_context.push()

    def setUp(self):
        self.client = self.app.test_client()

        username = TEST_DATA_USERNAME
        user = User.objects.filter(username=username).first()
        if not user:
            user = DefenseSourceCheckForm.create_user(username)
        assert user
        token = create_access_token(identity=user.id)
        self.client.set_cookie('localhost', 'token', token)

        init_test_data(user)

    def tearDown(self):
        clean_test_data()


def init_test_data(user):
    clean_test_data()

    for i in range(3):
        AssetTasks(
            vulSettings=VulSettings(
                taskId=TASK_ID
            ),
            vulResultId=ObjectId(),
            hostVulResultId=ObjectId(),
            sslResultId=ObjectId(),
            securityEventResultId=ObjectId(),
            contentResultId=ObjectId(),
            contentPrevResultId=ObjectId(),
            assetResultId=ObjectId(),
            assetPrevResultId=ObjectId(),
            httpResultId=ObjectId(),
            httpPrevResultId=ObjectId(),
            pingResultId=ObjectId(),
            pingPrevResultId=ObjectId(),
            sitePortraitId=ObjectId(),
            name='test',
            taskGroupType='web_security',
            triggerType='schedule',
            taskType='test',
            targetUrl=TARGET_URL,
            jobId=ObjectId(),
            uid=user.id,
            createTime=datetime.datetime.now()
        ).save()

    for i in range(3):
        Task(
            taskType=TaskType.vul.value,
            uid=user.id,
            jobId=ObjectId(),
            refId=ObjectId(),
            prevTaskId=ObjectId(),
            startTime=datetime.datetime.now(),
            taskSessionId=TASK_SESSION_ID,
            taskId=TASK_ID,
            nextExecDate=datetime.datetime.now(),
            endTime=datetime.datetime.now()
        ).save()

    for i in range(3):
        IgnoreStrategies(
            url=IGNORE_URL,
            key=KEY,
            ignoreType=InspectionStrategyIgnoreType.FALSE_POSITIVE,
            remarks='',
            switchStatus=InspectionStrategySwitchStatus.OPEN,
            createdAt=datetime.datetime.now(),
            updatedAt=datetime.datetime.now()
        ).save()

    for event_id in EVENT_ID_LIST:
        ScanEvents(
            event_id=event_id,
            event_type=random.choice((1, 2)),
            event_name=random.choice(('vuln', 'risk_link')),
            detail={
                'url': URL,
                'name': {'zh_cn': '跨站脚本攻击', 'en_us': 'Cross site scripting'},
                'vuln_type': [{'en_us': 'xss', 'zh_cn': '跨站脚本攻击'}],
                'payload': '''security='\"/><ScRiPt>confirm(0114)</ScRiPt>;PHPSESSID=telohilvidj6nd04gf3ve8q3f3"''',
                'description': {'zh_cn': '中文', 'en_us' : 'English'},
                'impact': {'zh_cn': '中文', 'en_us' : 'English'},
                'recommendation': {'zh_cn': '中文', 'en_us' : 'English'},
                'reference' : ['http://www.owasp.org/index.php/Cross_Site_Scripting'],
                'traffics':  [{
                    'type': 3,
                    'type_name': 'http',
                    'request': {
                        'b64content': '',
                    },
                    'response': {
                        'b64content': '',
                    },
                }],
                'key': KEY,
                'results': [],
            },
            severity=random.choice((2, 3, 4, 5)),
            task_id=TASK_ID,
            task_session_id=TASK_SESSION_ID,
            job_id=JOB_ID,
            user_id=str(user.id),
            target_url=TARGET_URL,
            target_id='',
            job_name=random.choice(('nscan', 'kscan', 'appscan')),
            created_at=datetime.datetime.now(),
            updated_at=datetime.datetime.now()
        ).save()


def clean_test_data():
    AssetTasks.objects.delete()
    Task.objects.delete()
    IgnoreStrategies.objects.delete()
    ScanEvents.objects.delete()
